解题笔记(10)——约瑟夫环问题

        约瑟夫环问题的原来描述为,设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。  稍微简化一下。

        问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。 

        思路:容易想到的就是用环链表来做,构建一个环链表,每个结点的编号为0, 1, ...... n-1。每次从当前位置向前移动m-1步,然后删除这个结点。最后剩下的结点就是胜利者。给出两种方法实现,一种是自定义链表操作,另一种用是STL库的单链表。不难发现,用STL库可以提高编写速度。

struct ListNode
{
	int num;        //编号
	ListNode *next; //下一个
	ListNode(int n = 0, ListNode *p = NULL) 
	{ num = n; next = p;}
};

//自定义链表实现
int JosephusProblem_Solution1(int n, int m)
{
	if(n < 1 || m < 1)
		return -1;

	ListNode *pHead = new ListNode(); //头结点
	ListNode *pCurrentNode = pHead;   //当前结点
	ListNode *pLastNode = NULL;       //前一个结点
	unsigned i;

	//构造环链表
	for(i = 1; i < n; i++)
	{
		pCurrentNode->next = new ListNode(i);
		pCurrentNode = pCurrentNode->next;
  • 13
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值